﻿using Pfz.AnimationManagement.Animations;
using Pfz.AnimationManagement.Abstract;
using Pfz.AnimationManagement.Animations.TimeManipulation;
using System;
using Pfz.AnimationManagement.Animations.Groups;
using System.Collections.Generic;
using Pfz.AnimationManagement.Animations.Conditions;

namespace Pfz.AnimationManagement.AnimationBuilders
{
	public class SequenceBuilder<TParent, TThis>:
		AnimationBuilder<TParent, TThis>
	{
        private SequentialAnimationGroup _animation;
        internal SequenceBuilder(TParent parent, SequentialAnimationGroup animation):
            base(parent)
        {
            _animation = animation;
        }

        public override TThis Add(IAnimation animation)
        {
            _animation.Add(animation);
            return This;
        }

        public TThis Wait(double seconds)
        {
            return Wait(TimeSpan.FromSeconds(seconds));
        }
        public TThis Wait(TimeSpan waitTime)
        {
            var animation = new Wait(waitTime);
            return Add(animation);
        }
		public TThis WaitCondition(Func<bool> condition)
		{
			if (condition == null)
				throw new ArgumentNullException("condition");

			var animation = new WaitCondition();
			animation.Condition = condition;
			return Add(animation);
		}

		public TThis Wait(Func<double> secondsGetter)
		{
			if (secondsGetter == null)
				throw new ArgumentNullException("secondsGetter");

			var animation = new ImperativeAnimation(_Wait(secondsGetter));
			return Add(animation);
		}
		private static IEnumerable<IAnimation> _Wait(Func<double> secondsGetter)
		{
			var seconds = secondsGetter();
			var time = TimeSpan.FromSeconds(seconds);
			var result = new Wait(time);
			yield return result;
		}
	}
    public sealed class SequenceBuilder<TParent>:
        SequenceBuilder<TParent, SequenceBuilder<TParent>>
    {
        internal SequenceBuilder(TParent parent, SequentialAnimationGroup animation):
            base(parent, animation)
        {
        }
        public TParent EndSequence()
        {
            return Parent;
        }
    }
}
